#include "encoder.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include <netdb.h>
#include "driver/gpio.h"
#include "board.h"

#define ESP_INTR_FLAG_DEFAULT 0
#define TAG "Encoder"

QueueHandle_t encoder_gpio_event_queue = NULL;

static unsigned int Value_count = 0;

static int Encoder_A1_Last_Value = 0;
static int Encoder_B1_Last_Value = 0;

static int Encoder_A1_Value = 0;
static int Encoder_B1_Value = 0;

static encoder_call encoder_call_event = NULL;

void encoder_set_cb(encoder_call cb)
{
   if (cb) {
         encoder_call_event = cb;
   }
}

void IRAM_ATTR encoder_gpio_isr_handler(void *arg){
 uint32_t GPIO_Queue_Data = 0;
 if(gpio_get_level(Encoder_K_PIN)){
  if(Value_count == 0){
   Encoder_A1_Last_Value = gpio_get_level(Encoder_A_PIN);
   Encoder_B1_Last_Value = gpio_get_level(Encoder_B_PIN);
   Value_count = 1;
  }else if(Value_count == 1){
   Encoder_A1_Value = gpio_get_level(Encoder_A_PIN);
   Encoder_B1_Value = gpio_get_level(Encoder_B_PIN);
   if(((Encoder_A1_Last_Value == 0 && Encoder_A1_Value == 1) && (Encoder_B1_Last_Value == 1 && Encoder_B1_Value == 0))\
      || ((Encoder_A1_Last_Value == 1 && Encoder_A1_Value == 0) && (Encoder_B1_Last_Value == 0 && Encoder_B1_Value == 1))){
      GPIO_Queue_Data = 1;
   }else if(((Encoder_A1_Last_Value == 0 && Encoder_A1_Value == 1) && (Encoder_B1_Last_Value == 0 && Encoder_B1_Value == 1))\
      || ((Encoder_A1_Last_Value == 1 && Encoder_A1_Value == 0) && (Encoder_B1_Last_Value == 1 && Encoder_B1_Value == 0))){
      GPIO_Queue_Data = 2;
   }
   Encoder_B1_Last_Value = 2;
   Encoder_A1_Last_Value = 2;
   Value_count = 0;
  }
 }else if(!gpio_get_level(Encoder_K_PIN)){
  GPIO_Queue_Data = 3;
  //esp_restart(); //软件复位
 }
 if(GPIO_Queue_Data != 0){
  xQueueSendFromISR(encoder_gpio_event_queue,&GPIO_Queue_Data,NULL);
 }
}

void Encoder_Init(void){
 gpio_config_t io_conf;
 io_conf.intr_type = GPIO_INTR_DISABLE;
 io_conf.mode = GPIO_MODE_INPUT;
 io_conf.pull_down_en = 0;
 io_conf.pull_up_en = 1;
 io_conf.pin_bit_mask = 1ull<<Encoder_B_PIN;
 gpio_config(&io_conf);

 io_conf.intr_type = GPIO_INTR_ANYEDGE;
 io_conf.pin_bit_mask = 1ull<<Encoder_A_PIN;
 gpio_config(&io_conf);

 io_conf.intr_type = GPIO_INTR_NEGEDGE;
 io_conf.pin_bit_mask = 1ull<<Encoder_K_PIN;
 gpio_config(&io_conf);

 gpio_install_isr_service(0);
 gpio_isr_handler_add(Encoder_A_PIN,encoder_gpio_isr_handler,(void * )Encoder_A_PIN);
 gpio_isr_handler_add(Encoder_K_PIN,encoder_gpio_isr_handler,(void * )Encoder_K_PIN);

 encoder_gpio_event_queue = xQueueCreate(1,sizeof(uint32_t));
 xTaskCreate(Encoder_scan,"Encoder_scan",1024*5,NULL,4,NULL);

}

char Encoder_Get_State(void){
 char Capure_Encoder_State = 0;
 if(pdTRUE == xQueueReceive(encoder_gpio_event_queue,&Capure_Encoder_State,(TickType_t) 0)){
  printf("Capure Encoder State:%d\r\n",Capure_Encoder_State);
  return Capure_Encoder_State;
 }
 return 0;
}

void Encoder_scan(void *pvParam){
 char Capure_Encoder_State = 0;
 while(1){
  if(pdTRUE == xQueueReceive(encoder_gpio_event_queue,&Capure_Encoder_State,(TickType_t) 0)){
   printf("Capure Encoder State:%d\r\n",Capure_Encoder_State);
   if (encoder_call_event) {
      encoder_call_event((int)Capure_Encoder_State);
   }
  }
  vTaskDelay(10/portTICK_PERIOD_MS);
 }
}
